package configs

import (
	"errors"
	"fmt"
	apis "gluenet/pkg/apis"
	"gluenet/pkg/gerrors"
	"gluenet/pkg/meta"
	"gluenet/pkg/platform/glue"
)

func GetConfig(ctx *apis.GlueContext) {
	var (
		err  error
		key  string
		kind string
		mode string
	)
	key = ctx.WebContext.URLParam("label")
	//kind = ctx.WebContext.URLParam("kind")
	mode = ctx.WebContext.URLParam("mode")

	ctx.Logger.Debugf("get config Label: %v %v %v", key, kind, mode)

	//校验label格式
	if err = ctx.Validate.Label(key, kind, mode, meta.KindConfig); err != nil {
		e := fmt.Errorf("validate label %v", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(e, nil))
		ctx.Logger.Errorf("%v", e)
		return
	}

	//查询数据库
	var cfgs *meta.Config
	if err = ctx.DataBase.ConfigGet(mode, key, &cfgs); err != nil {
		if errors.Is(err, gerrors.DataNotFind) {
			ctx.WebContext.JSON(apis.ResponseOK(nil))
			return
		}
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error: %v, or data is nil", err), nil))
		return
	}

	//返回结果解码，根据不同的应用
	cfg, _, err := apis.DecodeConfigValue(cfgs.ConfigValue, mode)
	if err != nil {
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall config %v", err), nil))
		ctx.Logger.Errorf("unmarshall config %v", err)
		return
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(map[string]interface{}{
		"label":    cfgs.Label,
		"name":     cfgs.Name,
		"platform": cfgs.Platform,
		"value":    cfg,
	}))
	ctx.Logger.Debugf("get config response bytes: %v", n)
}

func ListConfigs(ctx *apis.GlueContext) {
	var (
		err error
		//kind string
		//mode = apis.ModuleDefault
	)

	//kind = ctx.WebContext.URLParam("kind")
	//mode = ctx.WebContext.URLParam("mode")

	//查询数据库
	var cfgs []meta.Config
	if err = ctx.DataBase.ConfigListAll(&cfgs); err != nil {
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}
	if len(cfgs) == 0 {
		ctx.WebContext.JSON(apis.ResponseOK(nil))
		return
	}

	//返回结果
	cfg := make([]map[string]interface{}, len(cfgs))
	for k, v := range cfgs {
		cfg[k] = make(map[string]interface{}, 3)
		cfg[k]["label"] = v.Label
		cfg[k]["name"] = v.Name
		cfg[k]["platform"] = v.Platform
		cfg[k]["value"], cfg[k]["kind"], err = apis.DecodeConfigValue(v.ConfigValue, v.Platform)
		if err != nil {
			ctx.Logger.Errorf("unmarshall config %v", err)
			ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall config %v", err), nil))
			return
		}
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(cfg))
	ctx.Logger.Debugf("list config response bytes: %v", n)
}

func ListConfigsKind(ctx *apis.GlueContext) {
	var (
		err  error
		kind string
	)

	kind = ctx.WebContext.URLParam("kind")

	//查询数据库
	var cfgs []meta.Config
	if err = ctx.DataBase.ConfigKindList(kind, &cfgs); err != nil {
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}
	if len(cfgs) == 0 {
		ctx.WebContext.JSON(apis.ResponseOK(nil))
		return
	}

	//返回结果
	cfg := make([]map[string]interface{}, len(cfgs))
	for k, v := range cfgs {
		cfg[k] = make(map[string]interface{}, 3)
		cfg[k]["label"] = v.Label
		cfg[k]["name"] = v.Name
		cfg[k]["platform"] = v.Platform
		cfg[k]["value"], cfg[k]["kind"], err = apis.DecodeConfigValue(v.ConfigValue, v.Platform)
		if err != nil {
			ctx.Logger.Errorf("unmarshall config %v", err)
			ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall config %v", err), nil))
			return
		}
		if version, describe, err := apis.GetVersionAndDescribe(&v); err == nil {
			cfg[k]["version"] = version
			cfg[k]["describe"] = describe
		} else {
			cfg[k]["version"] = ""
			cfg[k]["describe"] = ""
		}
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(cfg))
	ctx.Logger.Debugf("list config response bytes: %v", n)
}

func GetDefaultConfigApplicationLevels(ctx *apis.GlueContext) {
	ctx.WebContext.JSON(apis.ResponseOK(glue.ConfigApplicationLevels()))
}
